package com.forsir.android.mhfinance;

import java.util.Calendar;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.app.DatePickerDialog.OnDateSetListener;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ExpandableListView.OnChildClickListener;

import com.forsir.android.mhfinance.helper.DateInterval;
import com.forsir.android.mhfinance.helper.DbAdapter;
import com.forsir.android.mhfinance.helper.FileFunctions;
import com.forsir.android.mhfinance.helper.ManageItemsActivity;
import com.forsir.android.mhfinance.storeObjects.Account;
import com.forsir.android.mhfinance.storeObjects.AccountsList;
import com.forsir.android.mhfinance.storeObjects.CategoryList;
import com.forsir.android.mhfinance.storeObjects.IStorable;
import com.forsir.android.mhfinance.storeObjects.Payment;
import com.forsir.android.mhfinance.storeObjects.PaymentList;
import com.forsir.android.mhfinance.storeObjects.Repeating;
import com.forsir.android.mhfinance.storeObjects.Subcategory;

public class Report extends ManageItemsActivity {
	private static final String TAG = "MHFinance";

	public static final String REQUEST_REPORT_TYPE = "report_type";
	public static final String REQUEST_CATEGORY_ID = "category_id";
	public static final String REQUEST_SUBCATEGORY_ID = "subcategory_id";
	public static final String REQUEST_ACCOUNT_ID = "account_id";

	// must correspond with array preferences_default_report
	public static final int TYPE_LIST = 1;
	public static final int TYPE_SUMMARY = 2;
	public static final int TYPE_ACCOUNTS = 3;
	public static final int TYPE_SUBCATEGORY = 4;
	// public static final int TYPE_CATEGORY = 5;

	private static final int REPORT_ACTIVITY = 101;
	private static final int SELECT_ACCOUNT_ACTIVITY = 102;
	private static final int SELECT_SUBCATEGORY_ACTIVITY = 103;
	// private static final int SELECT_CATEGORY_ACTIVITY = 104;
	private static final int SET_AMOUNT_ACTIVITY = 105;
	private static final int SHOW_PAYMENT_ACTIVITY = 106;
	private static final int PREFERENCES_ACTIVITY = 107;

	private static final int DATE_TYPE_DIALOG = 1;
	private static final int DATE_DIALOG = 2;
	private static final int DATE_TO_DIALOG = 3;

	private DbAdapter mDbHelper;
	private Account actualAccount = null;
	private Subcategory actualSubcategory = null;

	private ListView paymentsListView;
	private ExpandableListView categoryListView;
	private Button dateButton;
	private Button dateToButton;
	private ImageButton dateNextButton;
	private ImageButton datePreviousButton;
	private ImageButton menuButton;
	private Button categoryButton;
	private Button accountButton;
	private TextView sumWithdrawText;
	private TextView sumDepositText;
	private TextView sumSummaryText;
	private LinearLayout menuLayout;

	private final DateInterval mInterval = new DateInterval();
	private int mType;
	private boolean isMenuShown = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.report);

		mDbHelper = new DbAdapter(this, this);
		mDbHelper.open();

		paymentsListView = (ListView) findViewById(R.id.report_payment_list);
		categoryListView = (ExpandableListView) findViewById(R.id.report_category_list);
		dateButton = (Button) findViewById(R.id.report_date);
		dateToButton = (Button) findViewById(R.id.report_date_to);
		dateNextButton = (ImageButton) findViewById(R.id.report_right);
		datePreviousButton = (ImageButton) findViewById(R.id.report_left);
		menuButton = (ImageButton) findViewById(R.id.report_filter);
		categoryButton = (Button) findViewById(R.id.report_category);
		accountButton = (Button) findViewById(R.id.report_account);
		sumWithdrawText = (TextView) findViewById(R.id.report_sum_withdraw);
		sumDepositText = (TextView) findViewById(R.id.report_sum_deposit);
		sumSummaryText = (TextView) findViewById(R.id.report_sum_sum);
		menuLayout = (LinearLayout) findViewById(R.id.report_filter_layout);

		dateButton.setOnClickListener(clickDateListener);
		dateButton.setOnLongClickListener(longClickDateListener);
		dateToButton.setOnClickListener(clickDateToListener);
		dateToButton.setOnLongClickListener(longClickDateListener);
		dateNextButton.setOnClickListener(clickNextDateListener);
		// not working. If first date is set, button cannot be disabled
		// dateNextButton.setOnLongClickListener(longClickNextDateListener);
		datePreviousButton.setOnClickListener(clickPreviousDateListener);
		// datePreviousButton.setOnLongClickListener(longClickPreviousDateListener);
		menuButton.setOnClickListener(menuClickListener);
		categoryButton.setOnClickListener(categoryClickListener);
		categoryButton.setOnLongClickListener(longClickCategoryListener);
		accountButton.setOnClickListener(accountClickListener);
		accountButton.setOnLongClickListener(longClickAccountListener);
		paymentsListView.setOnItemClickListener(paymentsClickListener);
		categoryListView.setOnChildClickListener(subcategoryClickListener);

		PaymentList.currencyBefore = mPreferenceSettings.getString(getString(R.string.key_currency_before), getString(R.string.currency_before));
		PaymentList.currencyAfter = mPreferenceSettings.getString(getString(R.string.key_currency_after), getString(R.string.currency_after));
		PaymentList.loadFirstAndLastDate(mDbHelper);

		if (savedInstanceState != null) {
			mType = savedInstanceState.getInt(REQUEST_REPORT_TYPE, TYPE_SUMMARY);
			actualAccount = AccountsList.getAccountById(savedInstanceState.getLong(REQUEST_ACCOUNT_ID, -1));
			actualSubcategory = CategoryList.getSubcategoryById(savedInstanceState.getLong(REQUEST_SUBCATEGORY_ID, -1));
			mInterval.fillFromBundle(savedInstanceState);
		} else {
			final Bundle extras = getIntent().getExtras();
			if (extras != null) {
				mType = extras.getInt(REQUEST_REPORT_TYPE, TYPE_SUMMARY);
				actualAccount = AccountsList.getAccountById(extras.getLong(REQUEST_ACCOUNT_ID, -1));
				actualSubcategory = CategoryList.getSubcategoryById(extras.getLong(REQUEST_SUBCATEGORY_ID, -1));
				mInterval.fillFromBundle(extras);
			}
		}

		if (mInterval.isEmpty()) {
			mInterval.setType(DateInterval.TYPE_MONTH);
			mInterval.setDateFrom(Calendar.getInstance());
		}

		registerForContextMenu(paymentsListView);
		setInterval();
		fillData();
		changeMenuIcon();
		PaymentList.isChanged = false;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;
		Builder builder = null;

		switch (id) {
			case DATE_TYPE_DIALOG:
				builder = new AlertDialog.Builder(paymentsListView.getContext());
				builder.setTitle(R.string.select_type);

				builder.setItems(R.array.report_date_type, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialogArgument, int which) {
						switch (which) {
							case 0:
								mInterval.setType(DateInterval.TYPE_WEEK);
								break;
							case 1:
								mInterval.setType(DateInterval.TYPE_MONTH);
								break;
							case 2:
								mInterval.setType(DateInterval.TYPE_YEAR);
								break;
							case 3:
								mInterval.setDateTo(mInterval.getDateTo());
								mInterval.setType(DateInterval.TYPE_CUSTOM);
								break;
						}
						setInterval();
						fillData();
					}
				});

				dialog = builder.create();
				break;
			case DATE_DIALOG:
				dialog = new DatePickerDialog(dateButton.getContext(), dateSetListener, mInterval.getDateFrom().get(Calendar.YEAR), mInterval.getDateFrom().get(
				        Calendar.MONTH), mInterval.getDateFrom().get(Calendar.DAY_OF_MONTH));
				break;
			case DATE_TO_DIALOG:
				dialog = new DatePickerDialog(dateButton.getContext(), dateToSetListener, mInterval.getDateTo().get(Calendar.YEAR), mInterval.getDateTo().get(
				        Calendar.MONTH), mInterval.getDateTo().get(Calendar.DAY_OF_MONTH));
				break;
		}

		return dialog;
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
			case DATE_DIALOG:
				((DatePickerDialog) dialog).updateDate(mInterval.getDateFrom().get(Calendar.YEAR), mInterval.getDateFrom().get(Calendar.MONTH), mInterval.getDateFrom()
				        .get(Calendar.DAY_OF_MONTH));
				break;
			case DATE_TO_DIALOG:
				((DatePickerDialog) dialog).updateDate(mInterval.getDateTo().get(Calendar.YEAR), mInterval.getDateTo().get(Calendar.MONTH), mInterval.getDateTo().get(
				        Calendar.DAY_OF_MONTH));
				break;
		}
	}

	OnDateSetListener dateSetListener = new OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int month, int day) {
			mInterval.getDateFrom().set(year, month, day);
			setInterval();
			fillData();
		}
	};

	OnDateSetListener dateToSetListener = new OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int month, int day) {
			mInterval.getDateTo().set(year, month, day);
			setInterval();
			fillData();
		}
	};

	// must be run, after interval or report type is changed
	private void setInterval() {
		switch (mType) {
			case TYPE_LIST:
				dateButton.setLongClickable(true);
				categoryButton.setVisibility(View.VISIBLE);
				accountButton.setVisibility(View.VISIBLE);
				break;
			case TYPE_SUMMARY:
				dateButton.setLongClickable(false);
				mInterval.setType(DateInterval.TYPE_YEAR);
				categoryButton.setVisibility(View.VISIBLE);
				accountButton.setVisibility(View.VISIBLE);
				break;
			case TYPE_ACCOUNTS:
				dateButton.setLongClickable(true);
				categoryButton.setVisibility(View.VISIBLE);
				accountButton.setVisibility(View.GONE);
				break;
			case TYPE_SUBCATEGORY:
				dateButton.setLongClickable(true);
				categoryButton.setVisibility(View.GONE);
				accountButton.setVisibility(View.VISIBLE);
				break;
		}
		mInterval.findFirstDate();
		mInterval.moveToBoundaries(PaymentList.firstDate, PaymentList.lastDate);

		if (mInterval.getType() == DateInterval.TYPE_CUSTOM) {
			dateToButton.setVisibility(View.VISIBLE);
		} else {
			dateToButton.setVisibility(View.GONE);
		}
	}

	private void fillData() {
		switch (mType) {
			case TYPE_LIST:
				categoryListView.setVisibility(View.GONE);
				paymentsListView.setVisibility(View.VISIBLE);

				// very quick but cannot configure date format
				// paymentsListView.setAdapter(PaymentList.getCursorAdapterPaymentList(mDbHelper, this, getResources(), actualAccount, actualSubcategory, interval
				// .getDateFrom(), interval.getDateTo()));
				paymentsListView.setAdapter(PaymentList.getPaymentListAdapter(mDbHelper, this, getResources(), actualAccount, actualSubcategory, mInterval.getDateFrom(),
				        mInterval.getDateTo()));

				break;
			case TYPE_SUMMARY:
				categoryListView.setVisibility(View.GONE);
				paymentsListView.setVisibility(View.VISIBLE);
				paymentsListView.setAdapter(PaymentList.getSummaryMonthListAdapter(mDbHelper, this, getResources(), actualAccount, actualSubcategory, mInterval
				        .getDateFrom(), mInterval.getDateTo()));
				break;
			case TYPE_ACCOUNTS:
				categoryListView.setVisibility(View.GONE);
				paymentsListView.setVisibility(View.VISIBLE);
				paymentsListView.setAdapter(PaymentList.getAccountSummaryAdapter(mDbHelper, this, actualSubcategory, mInterval.getDateFrom(), mInterval.getDateTo()));
				break;
			case TYPE_SUBCATEGORY:
				paymentsListView.setVisibility(View.GONE);
				categoryListView.setVisibility(View.VISIBLE);
				categoryListView.setAdapter(PaymentList.getPaymentCategorySummaryAdapter(mDbHelper, this, actualAccount, mInterval.getDateFrom(), mInterval.getDateTo()));
				break;
			// case TYPE_CATEGORY:
			// paymentsListView.setVisibility(View.GONE);
			// categoryListView.setVisibility(View.VISIBLE);
			// categoryListView.setAdapter(PaymentList.getAdapterSubcategoryPaymentList(mDbHelper, this, getResources(), actualAccount, interval.getDateFrom(),
			// interval
			// .getDateTo()));
			// break;
		}

		sumDepositText.setText(PaymentList.getLastSumDepositFormated());
		sumWithdrawText.setText(PaymentList.getLastSumWithdrawFormated());
		sumSummaryText.setText(PaymentList.getLastSumFormated());
		dateButton.setText(mInterval.getDateString(getResources()));

		if (actualAccount == null) {
			accountButton.setText(R.string.all_accounts);
		} else {
			accountButton.setText(actualAccount.getName());
		}

		if (actualSubcategory == null) {
			categoryButton.setText(R.string.all_categories);
		} else {
			categoryButton.setText(actualSubcategory.getFullName());
		}

		if (mInterval.getDateFrom().after(PaymentList.firstDate)) {
			datePreviousButton.setEnabled(true);
		} else {
			datePreviousButton.setEnabled(false);
		}

		if (mInterval.getDateTo().after(PaymentList.lastDate)) {
			dateNextButton.setEnabled(false);
		} else {
			dateNextButton.setEnabled(true);
		}

		if (mInterval.getType() == DateInterval.TYPE_CUSTOM) {
			dateToButton.setText(mInterval.getDateToString(getResources()));
		}
	}

	private void changeMenuIcon() {
		boolean filtered = false;
		switch (mType) {
			case TYPE_LIST:
			case TYPE_SUMMARY:
				if (actualAccount != null || actualSubcategory != null) {
					filtered = true;
				}
				break;
			case TYPE_ACCOUNTS:
				if (actualSubcategory != null) {
					filtered = true;
				}
				break;
			case TYPE_SUBCATEGORY:
				if (actualAccount != null) {
					filtered = true;
				}
				break;
		}

		if (isMenuShown) {
			if (filtered) {
				menuButton.setImageResource(R.drawable.filter_close_filtered);
			} else {
				menuButton.setImageResource(R.drawable.filter_close);
			}
		} else if (filtered) {
			menuButton.setImageResource(R.drawable.filter_open_filtered);
		} else {
			menuButton.setImageResource(R.drawable.filter_open);
		}
	}

	private final OnClickListener clickDateListener = new OnClickListener() {
		public void onClick(View v) {
			showDialog(DATE_DIALOG);
		}
	};

	private final OnClickListener clickDateToListener = new OnClickListener() {
		public void onClick(View v) {
			showDialog(DATE_TO_DIALOG);
		}
	};

	private final OnLongClickListener longClickDateListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			showDialog(DATE_TYPE_DIALOG);
			return true;
		}
	};

	private final OnClickListener clickNextDateListener = new OnClickListener() {
		public void onClick(View v) {
			mInterval.moveToNext();
			fillData();
		}
	};

	private final OnLongClickListener longClickNextDateListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			mInterval.setDateFrom(PaymentList.lastDate);
			setInterval();
			fillData();
			return true;
		}
	};

	private final OnClickListener clickPreviousDateListener = new OnClickListener() {
		public void onClick(View v) {
			mInterval.moveToPrevious();
			fillData();
		}
	};

	private final OnLongClickListener longClickPreviousDateListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			mInterval.setDateFrom(PaymentList.firstDate);
			setInterval();
			fillData();
			return true;
		}
	};

	private final OnLongClickListener longClickAccountListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			actualAccount = null;
			fillData();
			changeMenuIcon();
			return true;
		}
	};

	private final OnLongClickListener longClickCategoryListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			actualSubcategory = null;
			fillData();
			changeMenuIcon();
			return true;
		}
	};

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		boolean change = false;
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
			case SELECT_ACCOUNT_ACTIVITY:
				if (resultCode == RESULT_OK) {
					final int index = data.getIntExtra(SelectAccount.RETURN_ACCOUNT_POSITION, -1);
					if (index >= 0) {
						actualAccount = AccountsList.getAccount(index);
					} else {
						actualAccount = null;
					}
				} else {
					if (actualAccount != null) {
						actualAccount = AccountsList.getAccountById(actualAccount.getId());
					}
				}
				change = true;
				break;
			case SELECT_SUBCATEGORY_ACTIVITY:
				if (resultCode == RESULT_OK) {
					final int catIndex = data.getIntExtra(SelectCategory.RETURN_CATEGORY_POSITION, -1);
					final int subIndex = data.getIntExtra(SelectCategory.RETURN_SUBCATEGORY_POSITION, -1);
					if (catIndex >= 0 && subIndex >= 0) {
						actualSubcategory = CategoryList.getSubcategory(catIndex, subIndex);
					} else {
						actualSubcategory = null;
					}
				} else {
					if (actualSubcategory != null) {
						actualSubcategory = CategoryList.getSubcategoryById(actualSubcategory.getId());
					}
				}
				change = true;
				break;
			case PREFERENCES_ACTIVITY:
				PaymentList.currencyBefore = mPreferenceSettings.getString(getString(R.string.key_currency_before), getString(R.string.currency_before));
				PaymentList.currencyAfter = mPreferenceSettings.getString(getString(R.string.key_currency_after), getString(R.string.currency_after));
				break;
			case REPORT_ACTIVITY:
			case SET_AMOUNT_ACTIVITY:
			case SHOW_PAYMENT_ACTIVITY:
			default: // if it can be edited, I must reload everything
				if (actualAccount != null) {
					actualAccount = AccountsList.getAccountById(actualAccount.getId());
				}
				if (actualSubcategory != null) {
					actualSubcategory = CategoryList.getSubcategoryById(actualSubcategory.getId());
				}
				break;
		}
		if (PaymentList.isChanged || change) {
			PaymentList.loadFirstAndLastDate(mDbHelper);
			setInterval();
			fillData();
			changeMenuIcon();
			PaymentList.isChanged = false;
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		if (mType == TYPE_LIST) {
			final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
			final Payment payment = PaymentList.getPayment(info.position);
			final MenuInflater inflater = getMenuInflater();
			if (payment.getRepeating().getType() == Repeating.TYPE_NONE) {
				inflater.inflate(R.menu.menu_payment, menu);
			} else {
				inflater.inflate(R.menu.menu_repeating_payment, menu);
			}
		}
	}

	// handle context menu
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		Intent intent;
		Payment payment;

		switch (item.getItemId()) {
			case R.id.menu_payment_new:
				intent = new Intent(Report.this, MHFinance.class);
				startActivityForResult(intent, SELECT_ACCOUNT_ACTIVITY);
				break;
			case R.id.menu_payment_delete:
				ShowDeleteDialog(PaymentList.getPayment(info.position));
				break;
			case R.id.menu_payment_edit:
				intent = new Intent(Report.this, SetAmount.class);
				payment = PaymentList.getPayment(info.position);
				if (payment != null) {
					intent.putExtra(SetAmount.REQUEST_PAYMENT_ID, payment.getId());
				}
				startActivityForResult(intent, SET_AMOUNT_ACTIVITY);
				break;
			case R.id.menu_repeating_payment_edit:
				intent = new Intent(Report.this, SetAmount.class);
				intent.putExtra(SetAmount.REQUEST_REPEATING, SetAmount.REPEATING_TYPE_NO_REPEATING);
				payment = PaymentList.getPayment(info.position);
				if (payment != null) {
					intent.putExtra(SetAmount.REQUEST_PAYMENT_ID, payment.getId());
				}
				startActivityForResult(intent, SET_AMOUNT_ACTIVITY);
				break;
			case R.id.menu_repeating_delete:
				ShowDeleteDialog(PaymentList.getPayment(info.position).getRepeating());
				break;
			case R.id.menu_repeating_edit:
				intent = new Intent(Report.this, SetAmount.class);
				intent.putExtra(SetAmount.REQUEST_REPEATING, SetAmount.REPEATING_TYPE_REPEATING);
				payment = PaymentList.getPayment(info.position);
				if (payment != null) {
					intent.putExtra(SetAmount.REQUEST_PAYMENT_ID, payment.getId());
				}
				startActivityForResult(intent, SET_AMOUNT_ACTIVITY);
				break;
		}
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		final MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_report, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// final Intent intent;
		switch (item.getItemId()) {
			case R.id.menu_backup:
				backup();
				return true;
			case R.id.menu_restore:
				restore();
				return true;
			case R.id.menu_export:
				export();
				return true;
			case R.id.menu_view_summary:
				mType = Report.TYPE_SUMMARY;
				setInterval();
				fillData();
				changeMenuIcon();
				return true;
			case R.id.menu_view_list:
				mType = Report.TYPE_LIST;
				setInterval();
				fillData();
				changeMenuIcon();
				return true;
			case R.id.menu_view_category:
				mType = Report.TYPE_SUBCATEGORY;
				setInterval();
				fillData();
				changeMenuIcon();
				return true;
			case R.id.menu_view_account:
				mType = Report.TYPE_ACCOUNTS;
				setInterval();
				fillData();
				changeMenuIcon();
				return true;
			case R.id.menu_preferences:
				final Intent intent = new Intent(Report.this, SetPreferences.class);
				startActivityForResult(intent, PREFERENCES_ACTIVITY);
				return true;
				/*
				 * maybe not needed case R.id.menu_report_filter_account: intent = new Intent(Report.this, SelectAccount.class);
				 * intent.putExtra(SelectAccount.REQUEST_ALL_ACCOUNTS, true); startActivityForResult(intent, SELECT_ACCOUNT_ACTIVITY); return true; case
				 * R.id.menu_report_filter_category: intent = new Intent(Report.this, SelectCategory.class); intent.putExtra(SelectCategory.REQUEST_ALL_CATEGORIES, true);
				 * startActivityForResult(intent, SELECT_SUBCATEGORY_ACTIVITY); return true;
				 */
		}
		return false;
	}

	private final OnClickListener menuClickListener = new OnClickListener() {
		public void onClick(View v) {
			if (isMenuShown) {
				menuLayout.setVisibility(View.GONE);
				isMenuShown = false;
			} else {
				menuLayout.setVisibility(View.VISIBLE);
				isMenuShown = true;
			}
			changeMenuIcon();
		}
	};

	private final OnClickListener accountClickListener = new OnClickListener() {
		public void onClick(View v) {
			final Intent intent = new Intent(Report.this, SelectAccount.class);
			intent.putExtra(SelectAccount.REQUEST_ALL_ACCOUNTS, true);
			startActivityForResult(intent, SELECT_ACCOUNT_ACTIVITY);
		}
	};

	private final OnClickListener categoryClickListener = new OnClickListener() {
		public void onClick(View v) {
			final Intent intent = new Intent(Report.this, SelectCategory.class);
			intent.putExtra(SelectCategory.REQUEST_ALL_CATEGORIES, true);
			startActivityForResult(intent, SELECT_SUBCATEGORY_ACTIVITY);
		}
	};

	private final OnItemClickListener paymentsClickListener = new OnItemClickListener() {
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			if (mType == TYPE_SUMMARY) {
				final Intent intent = new Intent(Report.this, Report.class);
				intent.putExtra(REQUEST_REPORT_TYPE, TYPE_LIST);
				if (actualSubcategory != null) {
					intent.putExtra(REQUEST_SUBCATEGORY_ID, actualSubcategory.getId());
				}
				if (actualAccount != null) {
					intent.putExtra(REQUEST_ACCOUNT_ID, actualAccount.getId());
				}
				intent.putExtra(DateInterval.DATE_TYPE, DateInterval.TYPE_MONTH);
				final Calendar startMonth = Calendar.getInstance();
				startMonth.set(mInterval.getDateFrom().get(Calendar.YEAR), position, 1);
				intent.putExtra(DateInterval.DATE_FROM, startMonth.getTimeInMillis());
				startActivityForResult(intent, REPORT_ACTIVITY);
			}

			if (mType == TYPE_LIST) {
				final Intent intent = new Intent(Report.this, ShowPayment.class);
				intent.putExtra(ShowPayment.REQUEST_POSITION, position);
				startActivityForResult(intent, SHOW_PAYMENT_ACTIVITY);
			}
		}
	};

	private final OnChildClickListener subcategoryClickListener = new OnChildClickListener() {
		public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
			final Intent intent = new Intent(Report.this, Report.class);
			intent.putExtra(REQUEST_REPORT_TYPE, TYPE_LIST);
			if (actualSubcategory != null) {
				intent.putExtra(REQUEST_SUBCATEGORY_ID, CategoryList.getSubcategory(groupPosition, childPosition).getId());
			}
			if (actualAccount != null) {
				intent.putExtra(REQUEST_ACCOUNT_ID, actualAccount.getId());
			}
			mInterval.fillIntent(intent);
			startActivityForResult(intent, REPORT_ACTIVITY);

			return true;
		}
	};

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		outState.putInt(REQUEST_REPORT_TYPE, mType);
		if (actualSubcategory != null) {
			outState.putLong(REQUEST_SUBCATEGORY_ID, actualSubcategory.getId());
		}
		if (actualAccount != null) {
			outState.putLong(REQUEST_ACCOUNT_ID, actualAccount.getId());
		}
		mInterval.fillBundle(outState);
	}

	@Override
	protected void processAddNewItem(String name) {
		// not used (yet)
	}

	@Override
	protected void processDeleteItem(IStorable item) {
		if (item.getClass() == Payment.class) {
			final Payment payment = (Payment) item;
			if (mDbHelper.deleteEntry(payment)) {
				Toast.makeText(this, String.format(getString(R.string.payment_was_deleted), payment.getName()), Toast.LENGTH_LONG).show();
			}
			payment.updateNextRemainder(mDbHelper);
		}
		if (item.getClass() == Repeating.class) {
			final Repeating repeating = (Repeating) item;
			final boolean result = mDbHelper.deleteEntries(new Payment(), DbAdapter.PAYMENT_REPEATING + "=" + repeating.getId());
			if (result && mDbHelper.deleteEntry(repeating)) {
				Toast.makeText(this, String.format(getString(R.string.repeating_was_deleted), repeating.getName()), Toast.LENGTH_LONG).show();
			}
		}
		fillData();
	}

	@Override
	protected void processEditItem(IStorable item, String name) {
		// not used (yet)
	}

	protected void export() {
		final FileFunctions export = new FileFunctions(mDbHelper, this);
		export.ExportPayments();
	}

	protected void backup() {
		final FileFunctions export = new FileFunctions(mDbHelper, this);
		export.Backup();
	}

	protected void restore() {
		final FileFunctions export = new FileFunctions(mDbHelper, this);
		export.Restore();

		PaymentList.loadFirstAndLastDate(mDbHelper);
		AccountsList.loadAll(mDbHelper);
		CategoryList.loadAll(mDbHelper);
		setInterval();
		fillData();
		changeMenuIcon();
	}
}
